/**
 * Pixel Cookers script for Redmine
 * author: Ludovic Meyer, Pixel Cookers - http://www.pixel-cookers.com
 * v3.0
 */
(function($, document, undefined) {
  $(document).ready(function() {
    var cfg = {
      "stopwatch.enabled": true,
      "stopwatch.precision": 3,
      "autofocus.time_entry": true
    };

    var sidebar_btn = $('<div id="sidebar_btn">&nbsp;</div>'),
        elem = $('#main:not(.nosidebar) #sidebar');

    sidebar_btn.on('click', toggle_sidebar);

    if (elem != undefined){
      elem.before(sidebar_btn);
      if ($.cookie('hide_sidebar') == 'yes'){
        $('#main').toggleClass('nosidebar');
      }
    }

    $('.controller-repositories .entry a[href$=".SyncTrash"], .controller-repositories .entry a[href$=".SyncID"], .controller-repositories .entry a[href$=".SyncIgnore"]').parent().parent().remove();

    if(cfg['autofocus.time_entry']) {
      if($('.controller-timelog.action-new').length > 0) {
        console.log('test');
        $('#time_entry_hours').focus();
      }
    }

    injectViewportMetaTag();
    injectAppleTouchIcons();

    if(cfg['stopwatch.enabled']) {
      $.cookie('timermaple', 1, {path: '/'});
      var stopwatchContainer = $(document.createElement('div')).attr('class', 'stopwatch-container');
      var runBtn = $(document.createElement('button')).attr('type', 'button').attr('id', 'stopwatch-run').attr('class', 'btn greydient').attr('value', 'Play').html('开始');
      var stopwatch = $(document.createElement('span')).attr('id', 'stopwatch').attr('class', 'icon icon-time');
      $('#time_entry_hours').parent().append(stopwatchContainer);
      stopwatchContainer.append(stopwatch).append(runBtn);
      stopwatch.html('00:00:00');

      $('#stopwatch-run').on('click', function(){
        var num = checkDecimal($('#time_entry_hours').attr('value'))*3600000;
        stopwatch.stopwatch({startTime: num}).stopwatch('toggle');
        stopwatch.bind('tick.stopwatch', function(e, elapsed){
          var num = elapsed/3600000;
          $('#time_entry_hours').attr('value', num.toFixed(cfg['stopwatch.precision']));
        })

        if($(this).attr('value') == 'Play') {
          $(this).attr('value', 'Pause').html('暂停');
        } else {
          $(this).attr('value', 'Play').html('开始');
        }

        return false;
      });

      $('#time_entry_hours').on('keyup', function(){
        stopwatch.html(makeTime(this.value));
      })

      if($.cookie("timermaple") == 1) {
        $('#stopwatch-run').trigger('click');
      }

      $('.controller-issues.action-show #issue-form input[type="submit"], .controller-timelog .edit_time_entry input[type="submit"], .controller-timelog .new_time_entry input[type="submit"]').on('click', function(){
        window.onbeforeunload = null;
      });
    }

    var loadTitle = $(document.createElement('h3')).html('用户自动计时');
    var loadBtn = $(document.createElement('button')).attr('type', 'button').attr('id', 'load-options').attr('class', 'btn greydient').html('开启自动计时');
    var loadResult = $(document.createElement('p')).attr('id', 'load-result');
    var mySidebar = $('.controller-my.action-account #sidebar');

    mySidebar.append(loadTitle).append(loadBtn).append(loadResult);
    if($.cookie("timermaple")) {
      $('#load-options').html('重新获取Cookie');
      $('#load-result').html('自动计时已启用');
    }
    loadBtn.on('click', function(){
      loadUserOptions();
    });
  });

  function loadUserOptions() {
    var api_key = $('#api-access-key').html()
    if(api_key != null){
      $.ajax({
        url: '/users/current.json?key='+api_key
      }).done(function( json ) {
            $.each(json.user.custom_fields, function(i, item) {
              if(item.name == "自动计时") {
                //console.log(item.name + item.value);
                $.cookie("timermaple", item.value, {path: '/'});
              }
            });
            $('#load-options').html('重新获取Cookie');
            $('#load-result').html('自动计时已启用');
          }).fail(function(){
            $('#load-result').html('获取自动计时失败');
          });
    } else {
      $('#load-result').html('无法获取Cookie,碰到这个问题请联系Maple')
    }
  }

  function toggle_sidebar(){
    $('#main').toggleClass('nosidebar');
    if($('#main').hasClass('nosidebar')){
      $.cookie('hide_sidebar', 'yes', {path: '/'});
      $.cookie('timermaple', 1, {path: '/'});
    }else{
      $.cookie('hide_sidebar', 'no', {path: '/'});
      $.cookie('timermaple', 1, {path: '/'});
    }
  }

  function injectViewportMetaTag(){
    var meta = $(document.createElement('meta'));
    meta.attr('name', 'viewport');
    meta.attr('content', 'width=device-width, initial-scale=1');
    $('head').append(meta);
  }

  var scripts = document.getElementsByTagName("script"),
      src = scripts[scripts.length-1].src;
  src = src.split('/');
  src = src[src.length-3];

  function injectAppleTouchIcons(){
    var link = $(document.createElement('link'));
    link.attr('rel', 'apple-touch-icon');
    link.attr('href', '/themes/'+src+'/images/touch/apple-touch-icon.png');
    $('head').append(link);

    link = $(document.createElement('link'));
    link.attr('rel', 'apple-touch-icon');
    link.attr('href', '/themes/'+src+'/images/touch/apple-touch-icon-72x72-precomposed.png');
    link.attr('sizes', '72x72');
    $('head').append(link);

    link = $(document.createElement('link'));
    link.attr('rel', 'apple-touch-icon');
    link.attr('href', '/themes/'+src+'/images/touch/apple-touch-icon-114x114-precomposed.png');
    link.attr('sizes', '114x114');
    $('head').append(link);
  }

  function leftPad(number, targetLength) {
    var output = number + '';
    while (output.length < targetLength) {
      output = '0' + output;
    }
    return output;
  }

  function checkDecimal(str) {
    if (!str) return 0;
    var ok = "";
    for (var i = 0; i < str.length; i++) {
      var ch = str.substring(i, i+1);
      if ((ch < "0" || "9" < ch) && ch != '.') {
        alert("Only numeric input is allowed!\n\n"
            + parseFloat(ok) + " will be used because '"
            + str + "' is invalid.\nYou may correct "
            + "this entry and try again.");
        return parseFloat(ok);
      }
      else ok += ch;
    }
    return parseFloat(str);
  }

  function makeTime(value) {
    var num = (checkDecimal(value)); // validates input
    if (num) {
      var hour = parseInt(num);
      num -= parseInt(num);
      num=num.toFixed(13)
      num *= 60;

      var min = parseInt(num);
      num -= parseInt(num);
      num=num.toFixed(13)
      num *= 60;
      var sec = parseInt(num);
      return leftPad(hour, 2) + ':' + leftPad(min, 2) + ':' + leftPad(sec, 2);
    } else {
      return '00:00:00';
    }
  }

})(jQuery, document);

/*!
 * jQuery Cookie Plugin v1.3
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2011, Klaus Hartl
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.opensource.org/licenses/GPL-2.0
 */
(function ($, document, undefined) {

  var pluses = /\+/g;

  function raw(s) {
    return s;
  }

  function decoded(s) {
    return decodeURIComponent(s.replace(pluses, ' '));
  }

  var config = $.cookie = function (key, value, options) {

    // write
    if (value !== undefined) {
      options = $.extend({}, config.defaults, options);

      if (value === null) {
        options.expires = -1;
      }

      if (typeof options.expires === 'number') {
        var days = options.expires, t = options.expires = new Date();
        t.setDate(t.getDate() + days);
      }

      value = config.json ? JSON.stringify(value) : String(value);

      return (document.cookie = [
        encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
        options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
        options.path    ? '; path=' + options.path : '',
        options.domain  ? '; domain=' + options.domain : '',
        options.secure  ? '; secure' : ''
      ].join(''));
    }

    // read
    var decode = config.raw ? raw : decoded;
    var cookies = document.cookie.split('; ');
    for (var i = 0, l = cookies.length; i < l; i++) {
      var parts = cookies[i].split('=');
      if (decode(parts.shift()) === key) {
        var cookie = decode(parts.join('='));
        return config.json ? JSON.parse(cookie) : cookie;
      }
    }

    return null;
  };

  config.defaults = {};

  $.removeCookie = function (key, options) {
    if ($.cookie(key) !== null) {
      $.cookie(key, null, options);
      return true;
    }
    return false;
  };

})(jQuery, document);

/*
 * jQuery stopwatch
 * https://github.com/robcowie/jquery-stopwatch/blob/master/jquery.stopwatch.js
 */
(function( $ ){

  function incrementer(ct, increment) {
    return function() { ct+=increment; return ct; };
  }

  function pad2(number) {
    return (number < 10 ? '0' : '') + number;
  }

  function defaultFormatMilliseconds(millis) {
    var x, seconds, minutes, hours;
    x = millis / 1000;
    seconds = Math.floor(x % 60);
    x /= 60;
    minutes = Math.floor(x % 60);
    x /= 60;
    hours = Math.floor(x % 24);
    // x /= 24;
    // days = Math.floor(x);
    return [pad2(hours), pad2(minutes), pad2(seconds)].join(':');
  }

  //NOTE: This is a the 'lazy func def' pattern described at http://michaux.ca/articles/lazy-function-definition-pattern
  function formatMilliseconds(millis, data) {
    // Use jintervals if available, else default formatter
    var formatter;
    if (typeof jintervals == 'function') {
      formatter = function(millis, data){return jintervals(millis/1000, data.format);};
    } else {
      formatter = defaultFormatMilliseconds;
    }
    formatMilliseconds = function(millis, data) {
      return formatter(millis, data);
    };
    return formatMilliseconds(millis, data);
  }

  var methods = {

    init: function(options) {
      var defaults = {
        updateInterval: 1000,
        startTime: 0,
        format: '{HH}:{MM}:{SS}',
        formatter: formatMilliseconds
      };

      // if (options) { $.extend(settings, options); }

      return this.each(function() {
        var $this = $(this),
            data = $this.data('stopwatch');

        // If the plugin hasn't been initialized yet
        if (!data) {
          // Setup the stopwatch data
          var settings = $.extend({}, defaults, options);
          data = settings;
          data.active = false;
          data.target = $this;
          data.elapsed = settings.startTime;
          // create counter
          data.incrementer = incrementer(data.startTime, data.updateInterval);
          data.tick_function = function() {
            var millis = data.incrementer();
            data.elapsed = millis;
            data.target.trigger('tick.stopwatch', [millis]);
            data.target.stopwatch('render');
          };
          $this.data('stopwatch', data);
        }

      });
    },

    start: function() {
      return this.each(function() {
        var $this = $(this),
            data = $this.data('stopwatch');
        // Mark as active
        data.active = true;
        data.timerID = setInterval(data.tick_function, data.updateInterval);
        $this.data('stopwatch', data);
      });
    },

    stop: function() {
      return this.each(function() {
        var $this = $(this),
            data = $this.data('stopwatch');
        clearInterval(data.timerID);
        data.active = false;
        $this.data('stopwatch', data);
      });
    },

    destroy: function() {
      return this.each(function(){
        var $this = $(this),
            data = $this.data('stopwatch');
        $this.stopwatch('stop').unbind('.stopwatch').removeData('stopwatch');
      });
    },

    render: function() {
      var $this = $(this),
          data = $this.data('stopwatch');
      $this.html(data.formatter(data.elapsed, data));
    },

    getTime: function() {
      var $this = $(this),
          data = $this.data('stopwatch');
      return data.elapsed;
    },

    toggle: function() {
      return this.each(function() {
        var $this = $(this);
        var data = $this.data('stopwatch');
        if (data.active) {
          $this.stopwatch('stop');
        } else {
          $this.stopwatch('start');
        }
      });
    },

    reset: function() {
      return this.each(function() {
        var $this = $(this);
        data = $this.data('stopwatch');
        data.incrementer = incrementer(data.startTime, data.updateInterval);
        data.elapsed = data.startTime;
        $this.data('stopwatch', data);
      });
    }
  };


  // Define the function
  $.fn.stopwatch = function( method ) {
    if (methods[method]) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if (typeof method === 'object' || !method) {
      return methods.init.apply(this, arguments);
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.stopwatch' );
    }
  };

})( jQuery );